/*
 * @lc app=leetcode.cn id=1760 lang=typescript
 *
 * [1760] 袋子里最少数目的球
 */

// @lc code=start
function minimumSize(nums: number[], maxOperations: number): number {
  // 计算需要操作多少次，可以分成每堆x个球
  const operations = (x: number): number => {
    let count = 0;
    for (let i = 0; i < nums.length; i++) {
      if (nums[i] % x === 0) {
        // 能整除的话，堆数减去1次
        count += nums[i] / x - 1;
      } else {
        // 不能整除,余数加1表示堆数，再减去1
        count += ((nums[i] / x) >> 0) + 1 - 1;
      }
    }
    return count;
  };

  // 二分查找范围是最少的球和最多球之间
  let min = 1;
  let max = Math.max(...nums);
  while (min < max) {
    let mid = min + ((max - min) >> 1);
    // 当前操作次数小于给定次数，表示球多了，减小球的数量
    if (operations(mid) <= maxOperations) max = mid;
    // 增大球的数量
    else min = mid + 1;
  }
  return min;
}
// @lc code=end
